package sim16;

/**
 * Abstract class defining a pipeline stage
 * @author Piotr
 *
 */
abstract class PipeStage {
	protected Instruction instr;
	protected boolean stalled;
	protected boolean causedStall;
	protected final int pipeID;
	
	PipeStage(int pipeID) {
		this.pipeID = pipeID;
		stalled = false;
		causedStall = false;
	}
	
	/**
	 * Returns the instruction currently in the pipe stage or a null.
	 * @return The instruction currently in the pipe stage, null if a bubble.
	 */
	public Instruction getInstruction() {
		return instr;
	}
	
	/**
	 * Like getInstruction(), but creates bubbles during a stall. Use for passing
	 * instructions between pipe stages.
	 * @return The instruction in the pipe stage, or a null if the stage is stalled.
	 */
	public Instruction passInstruction() {
		if (stalled) {
			return null;
		} else {
			return instr;
		}
	}
	
	/**
	 * The cycle method. Causes the pipeline stage to simulate a clock cycle.
	 * @param The previous stage in the pipeline to get instructions and data from.
	 * 			null for the first stage.
	 * @return the status of the stage. 1 if it holds an instruction (except nop), 0 otherwise
	 * @throws InvalidInstructionException 
	 */
	abstract int cycle(PipeStage prevStage) throws InvalidInstructionException;
}
